﻿// written by Tim Fischer, 2008
// All items beginning with an "x" are from the www.cross-browser.com library
// #pragma NoCompStart
/*
edCore.js  1.2
All events/shared functions for javascript
*/
// #pragma NoCompEnd

/*global $, DOMContentLoadedInit, DOMContentLoadedScheduler, ED, addDOMLoadEvent, 
  disableDrag, edAddEvent, edEnableDrag, edFixEvent, edHandleEvent, edRemoveEvent, 
  getViewPortHeight, getViewPortWidth, is, isElementInside, really_out, really_over, 
  xCamelize, xDef, xEvent, xFirstChild, xGetComputedStyle, xGetElementById, 
  xGetElementsByTagName, xHasPoint, xHeight, xLeft, xMoveTo, xNextSib, xNum, 
  xOpacity, xPageX, xPageY, xPreventDefault, xResizeTo, xScrollLeft, xScrollTop, 
  xStr, xStyle, xTop, xWidth, DOMContentLoadedCustom  */
_TF = top;
window.onDOMLoadEvents = [];
window.DOMContentLoadedInitDone = false;

function HTMLEncode(strHTML) {
    var div = document.createElement('div');
    div.innerText = strHTML;
    return div.innerHTML;
}
function HTMLDecode(strEncodeHTML) {
    var div = document.createElement('div');
    div.innerHTML = strEncodeHTML;
    return div.innerText;
}

var is = { ie: navigator.appName == 'Microsoft Internet Explorer', java: navigator.javaEnabled(), ns: navigator.appName == 'Netscape', ua: navigator.userAgent.toLowerCase(), version: parseFloat(navigator.appVersion.substr(21)) || parseFloat(navigator.appVersion), win: navigator.platform == 'Win32' };
is.mac = is.ua.indexOf('mac') >= 0; is.ff = is.ua.indexOf('firefox') >= 0; if (is.ua.indexOf('opera') >= 0) { is.ie = is.ns = false; is.opera = true; }
if (is.ua.indexOf('gecko') >= 0) { is.ie = is.ns = false; is.gecko = true; }

if (is.ff) { CollectGarbage = function() { }; }

function gup(name) { name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); var regexS = "[\\?&]" + name + "=([^&#]*)"; var regex = new RegExp(regexS); var results = regex.exec(window.location.href); if (results == null) return ""; else return results[1]; }

function replaceChar(s, c, n) { (s = s.split(''))[n] = c; return s.join(''); }
//function repChar(s, c, n) { (s = s.split(''))[--n] = c; return s.join('');}
//cross-browser.com functions
function xGetElementById(e) { if (typeof (e) == 'string') { if (document.getElementById) e = document.getElementById(e); else if (document.all) e = document.all[e]; else e = null; } return e; }
// Helpers
function _gE(o) {
    ///<summary>Helper function to call xGetElementById</summary>
    ///<param name="o">ID of element for xGetElementById</param>
    ///<returns>element</returns>
    return xGetElementById(o);
}

function xGetElementsByTagName(t, p) {
    var list = null;
    t = t || '*';
    p = _gE(p) || document;
    if (typeof p.getElementsByTagName != 'undefined') { // DOM1
        list = p.getElementsByTagName(t);
        if (t == '*' && (!list || !list.length)) list = p.all; // IE5 '*' bug
    }
    else { // IE4 object model
        if (t == '*') list = p.all;
        else if (p.all && p.all.tags) list = p.all.tags(t);
    }
    return list || [];
}

function xGetElementsByClassName(cName, pEle, tagName, fnCall) {
    var r = [];
    var re = new RegExp("(^|\\s)" + cName + "(\\s|$)");
    var e = xGetElementsByTagName(tagName, pEle); //pEle.getElementsByTagName(tagName);
    for (var i = 0; i < e.length; ++i) {
        if (re.test(e[i].className)) {
            r[r.length] = e[i];
            if (fnCall) { fnCall(e[i]); }
        }
    }
    return r;
}

function xClientHeight() {
    var v = 0, d = document, w = window;
    if ((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientHeight)
    { v = d.documentElement.clientHeight; }
    else if (d.body && d.body.clientHeight)
    { v = d.body.clientHeight; }
    else if (xDef(w.innerWidth, w.innerHeight, d.width)) {
        v = w.innerHeight;
        if (d.width > w.innerWidth) v -= 16;
    }
    return v;
}
function xClientWidth() {
    var v = 0, d = document, w = window;
    if ((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientWidth)
    { v = d.documentElement.clientWidth; }
    else if (d.body && d.body.clientWidth)
    { v = d.body.clientWidth; }
    else if (xDef(w.innerWidth, w.innerHeight, d.height)) {
        v = w.innerWidth;
        if (d.height > w.innerHeight) v -= 16;
    }
    return v;
}

function xEvent(evt) { var e = evt || window.event; if (!e) { return; } this.type = e.type; this.target = e.target || e.srcElement; this.relatedTarget = e.relatedTarget; if (xDef(e.pageX)) { this.pageX = e.pageX; this.pageY = e.pageY; } else if (xDef(e.clientX)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); } if (xDef(e.offsetX)) { this.offsetX = e.offsetX; this.offsetY = e.offsetY; } else if (xDef(e.layerX)) { this.offsetX = e.layerX; this.offsetY = e.layerY; } else { this.offsetX = this.pageX - xPageX(this.target); this.offsetY = this.pageY - xPageY(this.target); } this.keyCode = e.keyCode || e.which || 0; this.shiftKey = e.shiftKey; this.ctrlKey = e.ctrlKey; this.altKey = e.altKey; if (typeof e.type == 'string') { if (e.type.indexOf('click') != -1) { this.button = 0; } else if (e.type.indexOf('mouse') != -1) { this.button = e.button; } } } function xPreventDefault(e) { if (e && e.preventDefault) { e.preventDefault(); } else if (window.event) { window.event.returnValue = false; } } 

function xHasPoint(e, x, y, t, r, b, l) { if (!xNum(t)) { t = r = b = l = 0; } else if (!xNum(r)) { r = b = l = t; } else if (!xNum(b)) { l = r; b = t; } var eX = xPageX(e), eY = xPageY(e); return (x >= eX + l && x <= eX + xWidth(e) - r && y >= eY + t && y <= eY + xHeight(e) - b); } 
function xHeight(e, h) { if (!(e = _gE(e))) return 0; if (xNum(h)) { if (h < 0) h = 0; else h = Math.round(h); } else h = -1; var css = xDef(e.style); if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') { h = xClientHeight(); } else if (css && xDef(e.offsetHeight) && xStr(e.style.height)) { if (h >= 0) { var pt = 0, pb = 0, bt = 0, bb = 0; if (document.compatMode == 'CSS1Compat') { var gcs = xGetComputedStyle; pt = gcs(e, 'padding-top', 1); if (pt !== null) { pb = gcs(e, 'padding-bottom', 1); bt = gcs(e, 'border-top-width', 1); bb = gcs(e, 'border-bottom-width', 1); } else if (xDef(e.offsetHeight, e.style.height)) { e.style.height = h + 'px'; pt = e.offsetHeight - h; } } h -= (pt + pb + bt + bb); if (isNaN(h) || h < 0) return; else e.style.height = h + 'px'; } h = e.offsetHeight; } else if (css && xDef(e.style.pixelHeight)) { if (h >= 0) e.style.pixelHeight = h; h = e.style.pixelHeight; } return h; } function xLeft(e, iX) {
    if (!(e = _gE(e))) return 0; var css = xDef(e.style); if (css && xStr(e.style.left)) {
        if (xNum(iX)) e.style.left = iX + 'px'; else
        { iX = parseInt(e.style.left); if (isNaN(iX)) iX = xGetComputedStyle(e, 'left', 1); if (isNaN(iX)) iX = 0; } 
    } else if (css && xDef(e.style.pixelLeft)) { if (xNum(iX)) e.style.pixelLeft = iX; else iX = e.style.pixelLeft; } return iX;
} function xMoveTo(e, x, y) { xLeft(e, x); xTop(e, y); } function xNum() { for (var i = 0; i < arguments.length; ++i) { if (isNaN(arguments[i]) || typeof (arguments[i]) != 'number') return false; } return true; } function xOpacity(e, o) { var set = xDef(o); if (!(e = _gE(e))) return 2; if (xStr(e.style.opacity)) { if (set) e.style.opacity = o + ''; else o = parseFloat(e.style.opacity); } else if (xStr(e.style.filter)) { if (set) e.style.filter = 'alpha(opacity=' + (100 * o) + ')'; else if (e.filters && e.filters.alpha) { o = e.filters.alpha.opacity / 100; } } else if (xStr(e.style.MozOpacity)) { if (set) e.style.MozOpacity = o + ''; else o = parseFloat(e.style.MozOpacity); } else if (xStr(e.style.KhtmlOpacity)) { if (set) e.style.KhtmlOpacity = o + ''; else o = parseFloat(e.style.KhtmlOpacity); } return isNaN(o) ? 1 : o; } function xPageX(e) { var x = 0; e = _gE(e); while (e) { if (xDef(e.offsetLeft)) x += e.offsetLeft; e = xDef(e.offsetParent) ? e.offsetParent : null; } return x; } function xPageY(e) { var y = 0; e = _gE(e); while (e) { if (xDef(e.offsetTop)) y += e.offsetTop; e = xDef(e.offsetParent) ? e.offsetParent : null; } return y; } function xResizeTo(e, w, h) { xWidth(e, w); xHeight(e, h); } 

  function xStr(s) { for (var i = 0; i < arguments.length; ++i) { if (typeof (arguments[i]) != 'string') return false; } return true; } function xStyle(sProp, sVal) {
    var i, e; for (i = 2; i < arguments.length; ++i) {
        e = _gE(arguments[i]); if (e.style) {
            try
{ e.style[sProp] = sVal; } catch (err) { e.style[sProp] = ''; } 
        } 
    } 
} function xTop(e, iY) {
    if (!(e = _gE(e))) return 0; var css = xDef(e.style); if (css && xStr(e.style.top)) {
        if (xNum(iY)) e.style.top = iY + 'px'; else
        { iY = parseInt(e.style.top); if (isNaN(iY)) iY = xGetComputedStyle(e, 'top', 1); if (isNaN(iY)) iY = 0; } 
    } else if (css && xDef(e.style.pixelTop)) { if (xNum(iY)) e.style.pixelTop = iY; else iY = e.style.pixelTop; } return iY;
} function xWidth(e, w) { if (!(e = _gE(e))) return 0; if (xNum(w)) { if (w < 0) w = 0; else w = Math.round(w); } else w = -1; var css = xDef(e.style); if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') { w = xClientWidth(); } else if (css && xDef(e.offsetWidth) && xStr(e.style.width)) { if (w >= 0) { var pl = 0, pr = 0, bl = 0, br = 0; if (document.compatMode == 'CSS1Compat') { var gcs = xGetComputedStyle; pl = gcs(e, 'padding-left', 1); if (pl !== null) { pr = gcs(e, 'padding-right', 1); bl = gcs(e, 'border-left-width', 1); br = gcs(e, 'border-right-width', 1); } else if (xDef(e.offsetWidth, e.style.width)) { e.style.width = w + 'px'; pl = e.offsetWidth - w; } } w -= (pl + pr + bl + br); if (isNaN(w) || w < 0) return; else e.style.width = w + 'px'; } w = e.offsetWidth; } else if (css && xDef(e.style.pixelWidth)) { if (w >= 0) e.style.pixelWidth = w; w = e.style.pixelWidth; } return w; } function xNextSib(e, t) { e = _gE(e); var s = e ? e.nextSibling : null; while (s) { if (s.nodeType == 1 && (!t || s.nodeName.toLowerCase() == t.toLowerCase())) { break; } s = s.nextSibling; } return s; } function xFirstChild(e, t) { e = _gE(e); var c = e ? e.firstChild : null; while (c) { if (c.nodeType == 1 && (!t || c.nodeName.toLowerCase() == t.toLowerCase())) { break; } c = c.nextSibling; } return c; }

function getViewPortHeight() { var v = 0, d = document, w = window; if ((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientHeight) { v = d.documentElement.clientHeight; } else if (d.body && d.body.clientHeight) { v = d.body.clientHeight; } else if (xDef(w.innerWidth, w.innerHeight, d.width)) { v = w.innerHeight; if (d.width > w.innerWidth) v -= 16; } return v; };
function getViewPortWidth() { var v = 0, d = document, w = window; if ((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientWidth) { v = d.documentElement.clientWidth; } else if (d.body && d.body.clientWidth) { v = d.body.clientWidth; } else if (xDef(w.innerWidth, w.innerHeight, d.height)) { v = w.innerWidth; if (d.height > w.innerHeight) v -= 16; } return v; };

function xDef() { for (var i = 0; i < arguments.length; ++i) { if (typeof (arguments[i]) == 'undefined') return false; } return true; } function xCamelize(cssPropStr) { var i, c, a = cssPropStr.split('-'); var s = a[0]; for (i = 1; i < a.length; ++i) { c = a[i].charAt(0); s += a[i].replace(c, c.toUpperCase()); } return s; } function xGetComputedStyle(e, p, i) { if (!(e = _gE(e))) return null; var s, v = 'undefined', dv = document.defaultView; if (dv && dv.getComputedStyle) { s = dv.getComputedStyle(e, ''); if (s) v = s.getPropertyValue(p); } else if (e.currentStyle) { v = e.currentStyle[xCamelize(p)]; } else return null; return i ? (parseInt(v) || 0) : v; }
function edEnableDrag(id, fS, fD, fE, bEnabled) {
    var mx = 0, my = 0, el = _gE(id);

    function dragStart(e) {
        if (el.edDragEnabled) {
            var ev = new xEvent(e);
            xPreventDefault(e);
            mx = ev.pageX;
            my = ev.pageY;
            edAddEvent(document, 'mousemove', drag, false);
            edAddEvent(document, 'mouseup', dragEnd, false);
            if (fS) { fS(el, ev.pageX, ev.pageY, ev); }
        }
    }

    function drag(e) {
        var ev, dx, dy;
        xPreventDefault(e);
        ev = new xEvent(e);
        dx = ev.pageX - mx;
        dy = ev.pageY - my;
        mx = ev.pageX;
        my = ev.pageY;
        if (fD) { fD(el, dx, dy, ev); }
        else { xMoveTo(el, xLeft(el) + dx, xTop(el) + dy); }
    }

    function dragEnd(e) {
        var ev = new xEvent(e);
        xPreventDefault(e);
        edRemoveEvent(document, 'mouseup', dragEnd);
        edRemoveEvent(document, 'mousemove', drag);
        if (fE) { fE(el, ev.pageX, ev.pageY, ev); }
        if (edEnableDrag.drop) { edEnableDrag.drop(el, ev); }
    }
    
    if (el) {
        if (bEnabled == false) {
            el.edDragEnabled = false;
            edRemoveEvent(el, 'mousedown', dragStart);
        }
        else {
            el.edDragEnabled = true;
            edAddEvent(el, 'mousedown', dragStart, false);
        }
    }    
} 
edEnableDrag.drops = [];

function xScrollLeft(e, bWin) { var offset = 0; if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') { var w = window; if (bWin && e) w = e; if (w.document.documentElement && w.document.documentElement.scrollLeft) offset = w.document.documentElement.scrollLeft; else if (w.document.body && xDef(w.document.body.scrollLeft)) offset = w.document.body.scrollLeft; } else { e = _gE(e); if (e && xNum(e.scrollLeft)) offset = e.scrollLeft; } return offset; }
function xScrollTop(e, bWin) { var offset = 0; if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') { var w = window; if (bWin && e) w = e; if (w.document.documentElement && w.document.documentElement.scrollTop) offset = w.document.documentElement.scrollTop; else if (w.document.body && xDef(w.document.body.scrollTop)) offset = w.document.body.scrollTop; } else { e = _gE(e); if (e && xNum(e.scrollTop)) offset = e.scrollTop; } return offset; }
function xOffsetLeft(e) {
    if (!(e = xGetElementById(e))) return 0;
    if (xDef(e.offsetLeft)) return e.offsetLeft;
    else return 0;
}
function xOffsetTop(e) {
    if (!(e = xGetElementById(e))) return 0;
    if (xDef(e.offsetTop)) return e.offsetTop;
    else return 0;
}

// ie specific code to ensure mouse events don't cause "flicker".
function really_over(src) {  
    if(!window.event) {return true;  }
    var event = window.event;  
    var from = event.fromElement;  
    var to = event.toElement;  
    return ( to == src || src.contains(to) ) && !src.contains(from) && src != from;
}
function really_out(src) {  
    if(!window.event){return true; }
    var event = window.event;  
    var from = event.fromElement;  
    var to = event.toElement;  
    return (src == from || src.contains(from)) && !src.contains(to) && src != to;
}

// Recursively verifies that src element is inside dest element used in mouseover/out events
function isElementInside(src, dest) {
    while (src != null) { if (src.id == dest.id) { return true; } src = src.parentNode; }
    return false;
}

function edFixEvent(event) {
	///<summary> add W3C standard event methods</summary>
    event.preventDefault = function() { this.returnValue = false; };
    event.stopPropagation = function() { this.cancelBubble = true; };
	return event;
}

function edRemoveEvent(element, type, handler) {
	if (element.removeEventListener) {
		element.removeEventListener(type, handler, false);
	} else {
		// delete the event handler from the hash table
		if (element.events && element.events[type]) {
			delete element.events[type][handler.$$guid];
		}
	}
}

var EnumEvents = ["focus", "blur", "change", "click", "mousedown",
                  "mouseup", "mouseover", "keypress", "keydown",
                  "keyup", "keypress"];

function SafelyRemoveNode(node, andSelf) {
    ///<summary>Removes DOM Nodes and their repsective events properly to ensure no memory leaks</summary>
    ///<param name="node">DOM element</param>
    ///<param name="andSelf">set to true to remove the DOM element or false to only remove it's children</param>
    ///<returns>none</returns>

    if (node == undefined || node == null) { return; }
    while (node.hasChildNodes()) {
        if (node.lastChild.nodeName == 'IFRAME') {
            node.lastChild.src = "javascript:false;";
        }
        SafelyRemoveNode(node.lastChild);
    }
    if (andSelf != false) {
        if (node.events != undefined) { node.events = null; }
        if (node.innerText) { node.innerText = ''; }
        node.parentNode.removeChild(node); 
        }
};

function edReleaseEvents(el) {

    var helper = function(obj) {
        var i;
        for (i = 0; i < events.length; i++) {
            obj["on" + events[i]] = null;
        }
        if (obj.parent.hasChildNodes()) {
            for (i = 0; i < obj.parent.childNodes.length; i++) {
                helper(obj.parent.childNodes[i]);
            }
        }
    };
    helper(el);
};

function edHandleEvent(event) {
	var returnValue = true;
	// grab the event object (IE uses a global event object)
	event = event || edFixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
	// get a reference to the hash table of event handlers
	var handlers = this.events[event.type];
	for (var i in handlers) {
		this.$$edHandleEvent = handlers[i];
		if (this.$$edHandleEvent(event) == false) {returnValue = false;}
    }
	return returnValue;
}

// Function that adds DOMContentLoaded listeners to the array.
function addDOMLoadEvent(listener) {
	// If the DOMContentLoaded event has happened, run the function.
	if(window.DOMContentLoadedInitDone){listener();return;}
	window.onDOMLoadEvents[window.onDOMLoadEvents.length]=listener;
}

var nAddEvent;
if (document.addEventListener) {
    nAddEvent = function(element, type, handler) {
        element.addEventListener(type, handler, false);
    };
} else if (document.attachEvent) {
    nAddEvent = function(element, type, handler) {
        element.attachEvent("on" + type, handler);
    };
} else {
    nAddEvent = new Function; // not supported
} 

// Dean Edwards AddEvent - obliterates memory leaks in ie due to event handling
function edAddEvent(element, type, handler) {
	if (type == "DOMContentLoaded" || type == "domload") {addDOMLoadEvent(handler);return;}
	
	if (element.addEventListener) {
		element.addEventListener(type, handler, false);
	} else {
		// assign each event handler a unique ID
		if (!handler.$$guid) {
			handler.$$guid = edAddEvent.guid++;
		}
		// create a hash table of event types for the element
		if (!element.events) {
			element.events = {};
		}
		// create a hash table of event handlers for each element/event pair
		var handlers = element.events[type];
		if (!handlers) {
			handlers = element.events[type] = {};
			// store the existing event handler (if there is one)
			if (element["on" + type]) {
				handlers[0] = element["on" + type];
			}
		}
		// store the event handler in the hash table
		handlers[handler.$$guid] = handler;
		// assign a global event handler to do all the work
		element["on" + type] = edHandleEvent;
	}
}
// a counter used to create unique IDs
edAddEvent.guid = 1;
// End Dean Edwards addEvent.

//// Tino Zijdel - crisp@xs4all.nl This little snippet fixes the problem that the onload attribute on 
//// the body-element will overwrite previous attached events on the window object for the onload event.
//if (!window.addEventListener) {
//	document.onreadystatechange = function(){
//		if (window.onload && window.onload !== edHandleEvent) {
//			edAddEvent(window, 'load', window.onload);
//			window.onload = edHandleEvent;
//		}
//	};
//}

// Here are my functions for adding the DOMContentLoaded event to browsers other
// than Mozilla.
// Function to process the DOMContentLoaded events array.
function DOMContentLoadedInit() {
	// quit if this function has already been called
	if (window.DOMContentLoadedInitDone) {return;}
	window.DOMContentLoadedInitDone = true;
	// iterates through array of registered functions 
	for (var i=0; i<window.onDOMLoadEvents.length; i++) {
		var func = window.onDOMLoadEvents[i];
		func();
	}
}

function DOMContentLoadedScheduler() {
	// quit if the init function has already been called
	if (window.DOMContentLoadedInitDone) {return true;}

	// First, check for Safari or KHTML.
	// Second, check for IE.
	//if DOM methods are supported, and the body element exists
	//(using a double-check including document.body, for the benefit of older moz builds [eg ns7.1] 
	//in which getElementsByTagName('body')[0] is undefined, unless this script is in the body section)
	if(/KHTML|WebKit/i.test(navigator.userAgent)) {
		if(/loaded|complete/.test(document.readyState)) {
			DOMContentLoadedInit();
		} else {
			// Not ready yet, wait a little more.
			setTimeout(DOMContentLoadedScheduler, 250);
		}
	} else if(document.getElementById("__ie_onload")) {
		return true;
	}

	// Check for custom developer provided function.
	if(typeof DOMContentLoadedCustom === "function") {
		if(typeof document.getElementsByTagName !== 'undefined' && (document.getElementsByTagName('body')[0] !== null || document.body !== null)) {
			// Call custom function.
			if(DOMContentLoadedCustom()) {
				DOMContentLoadedInit();
			} else {
				// Not ready yet, wait a little more.
				setTimeout(DOMContentLoadedScheduler, 250);
			}
		}
	}
	return true;
}

// If addEventListener supports the DOMContentLoaded event.
if(document.addEventListener) {	document.addEventListener("DOMContentLoaded", DOMContentLoadedInit, false);}

// Schedule to run the init function.
setTimeout(DOMContentLoadedScheduler, 250);
// Just in case window.onload happens first, add it there too.
edAddEvent(window, "load", DOMContentLoadedInit);

/* for Internet Explorer */
/*@cc_on
	@if (@_win32 || @_win64)
	document.write("<script id=__ie_onload defer src=\"//:\"><\/script>");
	var script = document.getElementById("__ie_onload");
	script.onreadystatechange = function() {
		if (this.readyState == "complete") {
			DOMContentLoadedInit(); // call the onload handler
		}
	};
	@end
@*/

//Create the ED Object to be used throughout...
if (ED == null || typeof (ED) != "object") { var ED = new Object(); }
//ED.U - short for ED.Utilities - cookie functions
if (ED.U == null || typeof (ED.U) != "object") { ED.U = new Object(); }

if (ED.U["setCookie"] == null) {
    ED.U.setCookie = function(name, value, expire, path) {
        document.cookie = name + "=" + escape(value) +
                ((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
                "; path=" + ((!path) ? "/" : path);
        return null;
    };

    ED.U.getCookie = function(name) {
        var value = null, search = name + "=";
        if (document.cookie.length > 0) {
            var offset = document.cookie.indexOf(search);
            if (offset != -1) {
                offset += search.length;
                var end = document.cookie.indexOf(";", offset);
                if (end == -1) end = document.cookie.length;
                value = unescape(document.cookie.substring(offset, end));
            }
        }
        return value;
    };  // end of getCookie function

    ED.U.deleteCookie = function(name, path) {
        if (ED.U.getCookie(name)) {
            document.cookie = name + "=" +
                "; path=" + ((!path) ? "/" : path) +
                "; expires=" + new Date(0).toGMTString();
        }
    };
}

function getXMLHTTP() {
    var xmlhttp = false;
    if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
        try
        { xmlhttp = new XMLHttpRequest(); } catch (e) { xmlhttp = false; }
    } if (!xmlhttp && window.createRequest) {
        try
        { xmlhttp = window.createRequest(); } catch (e2) { xmlhttp = false; }
    } if (!xmlhttp) {
        try
        { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e3) { xmlhttp = false; }
    } return xmlhttp;
}

// The Magic of Asynchronous JS (Sortof)
function callWithSetTimeout(funcRef, a, b, c, d, e, f, g) {
    return function() { funcRef(a, b, c, d, e, f, g); };
}

function edRaiseEvent(controlID, func, arg1, arg2, arg3, arg4) {
    var fName = window[controlID + "_" + func];
    if (typeof fName == 'function') {
        document[fName(arg1, arg2, arg3, arg4)];
    }

}

/* ---------------------- ToolTips ----------------------- */
addTooltip = function(elemID, text, context) {

//$(document).ready(function() {
        _gE(elemID).title = text;
        $('#' + elemID).cluetip({
        splitTitle: '|',
            leftOffset: 25,
            cluetipClass: 'jtip',
            dropShadow: true,
            arrows: true,
            showTitle: false 
        });
  //      })
}

//addTooltip2 = function(elemID, text, context) {
//    _me = this;
//    _gE(elemID).ttip = text;

//    this.obj = _gE('edTT');
//    if (this.obj == null) {
//        this.obj = document.createElement('div');
//        this.obj.id = 'edTT';

//        this.objTop = document.createElement('div');
//        this.objTop.appendChild(document.createElement('span'));

//        this.objMid = document.createElement('div');
//        this.objMid.className = 'edmiddle';

//        this.obj2 = document.createElement('span');
//        this.obj2.id = 'edTTcon';

//        this.objMid.appendChild(this.obj2);
//        this.objBtm = document.createElement('div');

//        this.obj.appendChild(this.objTop);
//        this.obj.appendChild(this.objMid);
//        this.obj.appendChild(this.objBtm);
//        document.body.appendChild(this.obj);
//    }

//    _me.obj = this.obj;


//    this.showToolTip = function(event) {
//        this.e = event;
//        var r = '';
//        var y = this.e.clientY;
//        if (y < 255) { r = 'r'; }

//        _me.obj.firstChild.nextSibling.innerHTML = this.ttip;
//        _me.obj.style.display = 'block';
//        var st = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
//        if (is.mac) { st = 0; }
//        var leftPos = this.e.clientX - 100;
//        if (leftPos < 0) leftPos = 0;
//        _me.obj.style.left = leftPos + 'px';
//        if (r == 'r') {
//            _me.obj.firstChild.className = 'edtopr';
//            _me.obj.lastChild.className = 'edbottomr';
//            _me.obj.style.top = y + 16 + st + 'px';
//        }
//        else {
//            _me.obj.firstChild.className = 'edtop';
//            _me.obj.lastChild.className = 'edbottom';
//            _me.obj.style.top = y - _me.obj.offsetHeight - 1 + st + 'px';
//        }
//    }

//    this.hideToolTip = function() {
//        _me.obj.style.display = 'none';
//    }

//    edAddEvent(_gE(elemID), "mousemove", this.showToolTip);
//    edAddEvent(_gE(elemID), "mouseout", this.hideToolTip);

//}


/* ------------------- End ToolTops ---------------------*/


/**
* http://www.openjs.com/scripts/events/keyboard_shortcuts/
* Version : 2.01.B
* By Binny V A
* License : BSD

shortcut.add()
First Argument : The Shortcut Key Combination - String 
    The shortcut key combination should be specified in this format ... Modifier[+Modifier..]+Key. More about this in the Supported Keys section. 
Second Argument : Function to be called - Function 
    Specify the function here. This function will be called if the shortcut key is pressed. The event variable will be passed to it. 
Third Argument[OPTIONAL] : Options - Associative Array 
This argument must be an associative array with any of these three options...

    type - String 
        The event type - can be 'keydown','keyup','keypress'. Default: 'keydown' 
    disable_in_input - Boolean 
        If this is set to true, keyboard capture will be disabled in input and textarea fields. If these elements have focus, the keyboard shortcut will not work. This is very useful for single key shortcuts. Default: false 
    target - DOM Node 
        The element that should be watched for the keyboard event. Default : document 
    propagate - Boolean 
        Allow the event to propagate? Default : false 
    keycode - Integer 
        Watch for this keycode. For eg., the keycode '65' is 'a'. 

Example... 
----------------------------
{
'type':'keydown',
'propagate':false,
'disable_in_input':true,
'target':document,
'keycode':65
}

Example Code
----------------------------
shortcut.add("Ctrl+B",function() {
	alert("The bookmarks of your browser will show up after this alert...");
},{
	'type':'keydown',
	'propagate':true,
	'target':document
});


shortcut.remove()
Just one argument - the shortcut combination that was attached to a function earlier. Make sure that this is exactly the same string that you used while adding the shortcut.

Example Code
----------------------------
shortcut.add("Ctrl+B",function() {
	alert("Bold");
});
//Remove the shortcut
shortcut.remove("Ctrl+B");

Supported Keys
----------------------------
The shortcut keys should be specified in this format ... 

Modifier[+Modifier..]+Key 
Example...

Ctrl+A 
The valid modifiers are

Ctrl 
Alt 
Shift 
Meta 
You can specify a sequence without a modifier as well - like this...
----------------------------
shortcut.add("X",function() {
	alert("Hello!");
});

The valid Keys are...
----------------------------
All alpha/numeric keys - abc...xyz,01..89 
Special Characters - Every special character on a standard keyboard can be accessed. 
Special Keys... 
Tab 
Space 
Return 
Enter 
Backspace 
Scroll_lock 
Caps_lock 
Num_lock 
Pause 
Insert 
Home 
Delete 
End 
Page_up 
Page_down 
Left 
Up 
Right 
Down 
F1 
F2 
F3 
F4 
F5 
F6 
F7 
F8 
F9 
F10 
F11 
F12 
*/
var bindings = {};
window.shortcut = (function() {
    var keyEvent = is.ff ? 'keypress' : 'keydown';
    var defaultOptions = {
        type: keyEvent,
        propagate: false,
        disable: 'input textarea',
        target: document,
        keycode: false,
        description: 'unknown'
    };

    // Work around for Shift key bug created by using lowercase
    // as a result the shift+num combinationnation was broken
    var shiftNums = {
        '`': '~', '1': '!', '2': '@', '3': '#',
        '4': '$', '5': '%', '6': '^', '7': '&', '8': '*',
        '9': '(', '0': ')', '-': '_', '=': '+', ';': ':',
        "'": '"', ',': '<', '.': '>', '/': '?', '\\': '|'
    };

    // Special Keys and their codes
    var specialKeys = {
        'escape': 27, 'space': 32,
        'return': 13, 'enter': 13,
        'pause': 19, 'break': 19,
        'insert': 45, 'home': 36,
        'delete': 46, 'end': 35,

        'backspace': 8, 'esc': 27, 'tab': 9,
        'scrolllock': 145, 'scroll_lock': 145, 'scroll': 145,
        'capslock': 20, 'caps_lock': 20, 'caps': 20,
        'numlock': 144, 'num_lock': 144, 'num': 144,
        'pageup': 33, 'page_up': 33, 'pu': 33,
        'pagedown': 34, 'page_down': 34, 'pd': 34,

        'left': 37, 'up': 38, 'right': 39, 'down': 40,
        'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115,
        'f5': 116, 'f6': 117, 'f7': 118, 'f8': 119,
        'f9': 120, 'f10': 121, 'f11': 122, 'f12': 123
    };

    var modifierMapping = {
        ctrl: 'ctrl', control: 'ctrl',
        shift: 'shift', alt: 'alt',
        option: 'alt', meta: 'meta'
    };

    function triggeredInDisableTags(event, disableTags) {
        if (typeof disableTags !== 'string') return false;

        var element = event.target || event.srcElement;
        if (element.nodeType === 3)
            element = element.parentNode;

        return (disableTags.toLowerCase().indexOf(element.tagName.toLowerCase()) >= 0) ? true : false;
    }


    function matching(combination, options, e) {
        var i, key, modifier;
        var want = {};
        var keys = combination.split('+');

        //Find Which key is pressed
        var code = e.keyCode || e.which;
        var char = { 188: ',', 190: '.'}[code] || String.fromCharCode(code).toLowerCase();

        var count = 0;
        for (i = 0; i < keys.length; i++) {
            key = keys[i];
            modifier = modifierMapping[key];

            if (modifier) {
                want[modifier] = true;
                count++;
            }
            else
                if ((key.length > 1 && specialKeys[key] === code) ||
           (options.keycode === code) || (char === key) ||
           (e.shiftKey && shiftNums[char] === key))
                count++;
        } // End for (..)

        return (
      keys.length === count &&
      !!want.shift === !!e.shiftKey &&
      !!want.ctrl === !!e.ctrlKey &&
      !!want.alt === !!e.altKey &&
      !!want.meta === !!e.metaKey
    );
    }

    // Return the function to be called at keypress
    function makeKeypressedFun(combination, callback, options, obj, scope) {
        return function(e) {
            e = e || window.event;

            if (triggeredInDisableTags(e, options.disable) ||
				   !matching(combination, options, e)) return;

            if (typeof obj == "object" && scope == true) {
                obj.tmpShortcutCallback = callback;
                obj.tmpShortcutCallback(e, obj);
                delete obj.tmpShortcutCallback;
            }
            else {
                callback(e, obj);
            }

            //callback(e);
            if (!options.propagate) {
                e.stopPropagation && e.stopPropagation();
                e.preventDefault && e.preventDefault();
                e.cancelBubble = true;
                e.returnValue = false;
            }
        };
    }


    return /*shotcut*/{
    add: function(combination, callback, options, obj, scope) {
        options = options || {};

        for (var name in defaultOptions)
            if (!options.hasOwnProperty(name))
            options[name] = defaultOptions[name];

        var ele = options.target;

        if (typeof ele === 'string')
            ele = xGetElementById(ele);

        var func = makeKeypressedFun(combination, callback, options, obj, scope);

        var str1 = (ele.id != null) ? ele.id : ele.nodeName;
        if (ele.id != null) { str1 = ele.id.toLowerCase() + '_' + combination.toLowerCase(); }
        else {
            str1 = combination.toLowerCase();
        }



        bindings[str1] = {
            'callback': func,
            'target': ele,
            'event': options.type,
            'description': options.description
        };

        $(ele).bind(options.type, func);

//        //Attach the function with the event
//        if (ele.addEventListener)
//            ele.addEventListener(options.type, func, false);
//        else
//            if (ele.attachEvent)
//            ele.attachEvent('on' + options.type, func);
//        else
//            ele['on' + options.type] = func;
    },

    //Remove the shortcut - just specify the shortcut and I will remove the binding
    remove: function(combination, elename) {
        if (elename != null) { combination = ele.name.toLowerCase() + '_' + combination.toLowerCase(); }
        else {
            combination = combination.toLowerCase();
        }

        var binding = bindings[combination];

        delete bindings[combination];

        if (!binding) return;

        var type = binding.event;
        var ele = binding.target;
        var callback = binding.callback;

        if (ele.detachEvent)
            ele.detachEvent('on' + type, callback);
        else
            if (ele.removeEventListener)
            ele.removeEventListener(type, callback, false);
        else
            ele['on' + type] = false;
    },
    // get a html overview of all the current shortcuts
    getShortCutsInfo: function() {
        //        var str = '<table style="margin: 10 10 10 10">';
        //        for (prop in bindings) {
        //            str += '<tr><td align="center">' + prop + '</td><td> - ' + bindings[prop].description + '</td></tr>';
        //        }
        //        str += '</table>';
        //        return str;

        var str = '';
        for (prop in bindings) {
            str += 'event: ' + prop + ' - target: ' + bindings[prop].target.nodeName + ' - type: ' + bindings[prop].event + '\n\r';
        }

        return str;

    }
};

})();

// Replaces all instances of the given substring.
String.prototype.replaceAll = function(strTarget, strSubString) {
    var strText = this;
    var intIndexOfMatch = strText.indexOf(strTarget);

    while (intIndexOfMatch != -1) {
        strText = strText.replace(strTarget, strSubString)
        intIndexOfMatch = strText.indexOf(strTarget);
    }
    return (strText);
};


function IEremoveChild(elem) {
    var garbageBin = _gE('FilthyIEGarbageBin');
    if (!garbageBin) {
        garbageBin = new Element('div', { 'id': 'FilthyIEGarbageBin', 'style': 'display: none' });
        document.body.appendChild(garbageBin);
    }    // move the element to the garbage bin 
    garbageBin.adopt(elem);
    garbageBin.set('html', '');
    delete elem;
} 